<!-- mosowe-canvas-image -->
<template>
	<view class="mosowe-canvas-image">
		<view class="slot-view" @click="createCanvas">
			<slot></slot>
		</view>
		<view class="canvas-wrap-box">
			<!-- 主面板绘制 -->
			<canvas
				class="canvas-wrap"
				canvas-id="canvas"
				:style="'width: ' + width + 'px; height: ' + height + 'px;'"
			></canvas>
			<!-- 这个是用来绘制圆形图片的 -->
			<canvas
				class="canvas-wrap"
				canvas-id="canvas-arc"
				:style="'width: ' + canvasArcWidth + 'px; height: ' + canvasArcHeight + 'px;'"
			></canvas>
		</view>
	</view>
</template>

<script>
import QR from "./wxqrcode.js"
export default {
	name: "mosowe-canvas-image",
	components: {},
	props: {
		imgType: {
			// 图片类型
			type: String,
			default: "jpg",
			validator: () => {
				return ["jpg", "png"]
			},
		},
		compress: {
			// 是否开启压缩
			type: Boolean,
			default: false,
		},
		compressSize: {
			// 压缩界限，超过界限压缩，默认2M
			type: [Number, String],
			default: 1024 * 1024 * 2,
		},
		showPreview: {
			// 生成图像后是否预览
			type: Boolean,
			default: false,
		},
		height: {
			// canvas高度
			type: [String, Number],
			default: 200,
		},
		width: {
			// canvas宽度
			type: [String, Number],
			default: 200,
		},
		lists: {
			type: Array,
			default: () => {
				return []
			},
		},
	},
	data() {
		return {
			canvas: null,
			listsIndex: 0,
			listsLength: 0,
			canvasArc: null,
			canvasArcWidth: 100,
			canvasArcHeight: 100,
			compressQuality: 20,
			compressQualityH5: 5,
		}
	},
	watch: {},
	// 组件实例化之前
	beforeCreate() {},
	// 组件创建完成
	created() {
		this.canvas = uni.createCanvasContext("canvas", this)
		this.canvasArc = uni.createCanvasContext("canvas-arc", this)
	},
	// 组件挂载之前
	beforeMount() {},
	// 组件挂载之后
	mounted() {},
	// 组件数据更新时
	beforeUpdate() {},
	// 组价更新
	updated() {},
	// 组件销毁前
	beforeDestroy() {},
	// 组件销毁后
	destroyed() {},
	// 页面方法
	methods: {
		// 开始绘制
		createCanvas() {
			console.log(111, "111")
			this.clearCanvas()

			if (this.lists.length === 0) {
				uni.showToast({
					title: "lists不能为空",
					icon: "none",
				})
				return
			}
			this.listsIndex = 0
			this.listsLength = this.lists.length - 1
			uni.showLoading({
				title: "正在生成图片...",
				mask: true,
			})
			setTimeout(() => {
				uni.hideLoading()
			}, 10000)
			try {
				this.dataDrawCanvas()
			} catch (e) {
				//TODO handle the exception
				console.log(e, "dataDrawCanvas")
			}
		},
		// 数据绘制
		async dataDrawCanvas() {
			let item = this.lists[this.listsIndex]
			if (item.type === "image") {
				// 图片
				if (item.content.indexOf("https://") > -1) {
					// https://网络图片
					// #ifndef H5
					// 非H5
					this.downloadImageNotH5(item)
					// #endif
					// #ifdef H5
					// H5
					this.downloadImageH5(item)
					// #endif
				} else {
					// 本地选择图片
					if (this.compress && item.hasOwnProperty("file") && item.file.size > this.compressSize) {
						// 大于限制2M压缩
						this.compressImage(item)
					} else {
						if (item.arc) {
							this.drawImageArc(item)
						} else {
							this.drawImage(item)
						}
					}
				}
			} else if (item.type === "text") {
				// 文本
				this.drawText(item)
			} else if (item.type === "rect") {
				// 矩形（线条）
				this.drawRect(item)
			} else if (item.type === "arc") {
				// 圆形
				this.drawArc(item)
			} else if (item.type === "qr") {
				// 二维码
				this.drawQR(item)
			}
		},
		// #ifndef H5
		// https图片下载本地并绘制，非H5
		downloadImageNotH5(item) {
			uni.downloadFile({
				url: item.content,
				header: {
					"Access-Control-Allow-Origin": "*",
				},
				success: (res) => {
					item.content = res.tempFilePath
					if (item.arc) {
						this.drawImageArc(item)
					} else {
						this.drawImage(item)
					}
				},
				fail: (res) => {
					console.log(res)
				},
			})
		},
		// #endif
		// #ifdef H5
		// https图片下载本地并绘制，H5
		downloadImageH5(item) {
			console.log(item, "item")
			let image = null
			image = new Image()
			image.setAttribute("crossOrigin", "anonymous")
			image.crossOrigin = "Anonymous"
			image.src = item.content
			image.onload = () => {
				let canvas = document.createElement("canvas")
				canvas.width = item.width
				canvas.height = item.height
				let ctx = canvas.getContext("2d")
				ctx.drawImage(image, 0, 0, item.width, item.height)
				let dataURL = canvas.toDataURL("image/png")
				if (item.arc) {
					// 绘制圆形
					item.content = dataURL
					this.drawImageArc(item)
				} else {
					this.canvas.globalAlpha = item.hasOwnProperty("globalAlpha") ? item.globalAlpha : 1
					this.canvas.drawImage(
						dataURL,
						item.x,
						item.y,
						item.hasOwnProperty("width") ? item.width : this.width,
						item.hasOwnProperty("height") ? item.height : this.height
					)
					console.log(dataURL, "dataURL")
					this.checkDrawOver()
				}
			}
		},
		// #endif
		// 图片压缩
		compressImage(item) {
			uni.showLoading({
				title: "压缩中...",
				mask: true,
			})
			// 非H5压缩
			// #ifndef H5
			uni.compressImage({
				src: item.content,
				quality: this.compressQuality,
				success: (res) => {
					uni.showLoading({
						title: "正在生成图片...",
						mask: true,
					})
					item.content = res.tempFilePath
					if (item.arc) {
						this.drawImageArc(item)
					} else {
						this.drawImage(item)
					}
				},
				fail: (res) => {
					console.log(res)
					uni.showToast({
						title: "压缩失败",
						icon: "none",
					})
				},
			})
			// #endif
			// H5压缩
			// #ifdef H5
			let image = new Image()
			image.setAttribute("crossOrigin", "anonymous")
			image.crossOrigin = "Anonymous"
			image.src = item.content
			image.onload = () => {
				let canvas = document.createElement("canvas")
				canvas.width = item.width
				canvas.height = item.height
				let ctx = canvas.getContext("2d")
				ctx.drawImage(image, 0, 0, item.width, item.height)
				let dataURL = canvas.toDataURL("image/png")
				item.content = dataURL
				if (item.arc) {
					this.drawImageArc(item)
				} else {
					this.drawImage(item)
				}
			}
			// #endif
		},
		// 圆形图片另外绘制canvas,png格式
		drawImageArc(item) {
			this.canvasArc.clearRect(0, 0, this.canvasArcWidth, this.canvasArcHeight)
			this.canvasArcWidth = item.arcR * 2
			this.canvasArcHeight = item.arcR * 2
			this.canvasArc.save()
			let arcT = setTimeout(() => {
				clearTimeout(arcT)
				this.canvasArc.arc(item.arcR, item.arcR, item.arcR, 0, 2 * Math.PI)
				this.canvasArc.clip()
				// this.canvasArc.closePath();

				this.canvasArc.drawImage(item.content, item.arcX, item.arcY, item.width, item.height)
				this.canvasArc.draw(
					false,
					setTimeout(() => {
						let t = setTimeout(() => {
							clearTimeout(t)
							uni.canvasToTempFilePath(
								{
									x: 0,
									y: 0,
									width: item.arcR * 2,
									height: item.arcR * 2,
									fileType: "png",
									canvasId: "canvas-arc",
									success: (res) => {
										item.width = item.arcR * 2
										item.height = item.arcR * 2
										item.content = res.tempFilePath
										this.drawImage(item)
									},
									fail: (res) => {
										console.log(res)
									},
									complete: () => {
										this.canvasArc.restore()
										this.canvasArc.fillRect(0, 0, 0, 0)
										this.canvasArc.clearRect(0, 0, this.canvasArcWidth, this.canvasArcHeight)
									},
								},
								this
							)
						}, 100)
					})
				)
			}, 100)
		},
		// 图片绘制
		drawImage(item) {
			console.log(item, "item222")
			this.canvas.globalAlpha = item.hasOwnProperty("globalAlpha") ? item.globalAlpha : 1
			this.canvas.drawImage(
				item.content,
				item.x,
				item.y,
				item.hasOwnProperty("width") ? item.width : this.width,
				item.hasOwnProperty("height") ? item.height : this.height
			)
			this.checkDrawOver()
		},
		// 文本绘制
		drawText(item) {
			this.canvas.setFillStyle(item.hasOwnProperty("color") ? item.color : "#000000")
			this.canvas.setFontSize(item.hasOwnProperty("size") ? item.size : 20)
			this.canvas.setTextAlign(item.hasOwnProperty("align") ? item.align : "left")
			this.canvas.globalAlpha = item.hasOwnProperty("globalAlpha") ? item.globalAlpha : 1

			if (item.maxWidth) {
				this.canvas.fillText(item.content, item.x, item.y, item.maxWidth)
			} else {
				this.canvas.fillText(item.content, item.x, item.y)
			}
			this.checkDrawOver()
		},

		// 矩形（线条）绘制
		drawRect(item) {
			this.canvas.setFillStyle(item.hasOwnProperty("color") ? item.color : "#000000")
			this.canvas.globalAlpha = item.hasOwnProperty("globalAlpha") ? item.globalAlpha : 1
			this.canvas.fillRect(item.x, item.y, item.width, item.height)
			this.checkDrawOver()
		},

		// 圆形绘制
		drawArc(item) {
			this.canvas.arc(item.arcX, item.arcY, item.arcR, 0, 2 * Math.PI)
			this.canvas.setFillStyle(item.hasOwnProperty("color") ? item.color : "#000000")
			this.canvas.globalAlpha = item.hasOwnProperty("globalAlpha") ? item.globalAlpha : 1
			this.canvas.fill()
			this.canvas.closePath()
			this.checkDrawOver()
		},

		// 二维码绘制
		drawQR(item) {
			let len = item.content.length
			let typeNumber = Math.ceil(len / 16)
			if (typeNumber < 4) {
				typeNumber = 4
			}
			item["qr"] = QR.createQrCodeImg(item.content, {
				size: parseInt(300),
				typeNumber: typeNumber,
			})
			this.canvas.globalAlpha = item.hasOwnProperty("globalAlpha") ? item.globalAlpha : 1
			this.canvas.drawImage(
				item.qr,
				item.x,
				item.y,
				item.hasOwnProperty("width") ? item.width : this.width,
				item.hasOwnProperty("height") ? item.height : this.height
			)
			this.checkDrawOver()
		},

		// 判断是否绘制完
		checkDrawOver() {
			if (this.listsIndex < this.listsLength) {
				// lists未画完
				this.listsIndex++
				this.dataDrawCanvas()
			} else {
				this.canvasImage()
			}
		},

		// 绘制到画布并生成图片
		canvasImage() {
			this.listsIndex = 0
			this.canvas.draw(false, () => {
				setTimeout(() => {
					uni.canvasToTempFilePath(
						{
							x: 0,
							y: 0,
							width: Number(this.width),
							height: Number(this.height),
							fileType: this.imgType,
							canvasId: "canvas",
							success: (res) => {
								this.$emit("canvasImage", res.tempFilePath)
								if (this.showPreview) {
									this.showPreviewFn(res.tempFilePath)
								}
							},
							fail: (res) => {
								console.log(res)
							},
							complete: () => {
								uni.hideLoading()
							},
						},
						this
					)
				}, 500)
			})
		},
		// 预览图
		showPreviewFn(img) {
			uni.previewImage({
				current: 0,
				urls: [img],
			})
		},
		// 清空画布
		clearCanvas() {
			this.canvas.clearRect(0, 0, this.width, this.height)
		},
	},
}
</script>

<style lang="scss" scoped>
.mosowe-canvas-image {
	overflow: hidden;
	.canvas-wrap-box {
		overflow: hidden;
		height: 0;
		width: 0;
		position: fixed;
		left: 200%;
		// top: 0;
		top: var(--status-bar-height);
	}
	.canvas-wrap {
		overflow: hidden;
		height: 0;
		width: 0;
	}
}
</style>
